//-----------------------------------------------------------------------------
// Copyright (c) 2011 David Waby
// Initially created on 07/11/2011
//-----------------------------------------------------------------------------

#include "Global.h"
#include "CharacterSheet.h"

//-----------------------------------------------------------------------------
CharacterSheet::CharacterSheet()
:	m_level(0)
,	m_requiredXP(0)
,	m_xp(0)
,	m_hp(0)
,	m_skillPoints(0)
{
	// Reset all of the stats
	ClearPrimaryStats();
} 
	
//-----------------------------------------------------------------------------
CharacterSheet::~CharacterSheet()
{
}

//-----------------------------------------------------------------------------
void CharacterSheet::InitSetLevel(int const i_level)
{
	m_level = i_level;
}

//-----------------------------------------------------------------------------
void CharacterSheet::InitSetPrimaryStat(PrimaryStats::Enum const i_stat, int const i_value)
{
	m_primaryStats[i_stat] = i_value;
}

//-----------------------------------------------------------------------------
void CharacterSheet::Init()
{
	CalculateXPForNextLevel();
	CalculateDerivedStats();
	m_hp = static_cast<int>(m_derivedStats[DerivedStats::HitPoints]);
}

//-----------------------------------------------------------------------------
void CharacterSheet::IncreaseXP(int const i_xp)
{
	m_xp += i_xp;

	// Loop incase this XP amount causes more than one level increase
	while (m_xp >= m_requiredXP)
	{
		IncreaseLevel();
		CalculateSkillPoints();
		CalculateXPForNextLevel();
	}
}

//-----------------------------------------------------------------------------
bool CharacterSheet::AssignSkillPoint(PrimaryStats::Enum const i_stat)
{
	// Make sure we have skill points to spend
	if (m_skillPoints)
	{
		++m_primaryStats[i_stat];

		// Recalculate stats after increase
		CalculateDerivedStats();

		return true;
	}

	return false;
}

//-----------------------------------------------------------------------------
void CharacterSheet::IncreaseLevel()
{
	// Increase the level
	++m_level;
}

//-----------------------------------------------------------------------------
void CharacterSheet::ClearPrimaryStats()
{
	for (int counter = 0; counter < PrimaryStats::Noof; ++counter)
	{
		m_primaryStats[counter] = 0;
	}
}

//-----------------------------------------------------------------------------
void CharacterSheet::CalculateSkillPoints()
{
	// Give the character the correct skill points to spend
	m_skillPoints += m_level + 10;
}

//-----------------------------------------------------------------------------
void CharacterSheet::CalculateXPForNextLevel()
{
	// Work out the required xp to achieve the next level
	int const nextLevel = m_level + 1;
	m_requiredXP = (static_cast<int>(nextLevel*((nextLevel-1.f)*0.5f)) * 1000);
}

//-----------------------------------------------------------------------------
void CharacterSheet::CalculateDerivedStats()
{
	m_derivedStats[DerivedStats::ActionPoints] = static_cast<int>((m_primaryStats[PrimaryStats::Agility]*0.5f)*5.0f);
	m_derivedStats[DerivedStats::Dodge] = m_primaryStats[PrimaryStats::Agility];
	m_derivedStats[DerivedStats::CriticalStrike] = m_primaryStats[PrimaryStats::Luck];
	m_derivedStats[DerivedStats::HealingRate] = static_cast<int>(MAX(1.0f, (m_primaryStats[PrimaryStats::Stamina]*0.33f)));
	m_derivedStats[DerivedStats::HitPoints] = static_cast<int>(15.0f+(2.0f*m_primaryStats[PrimaryStats::Stamina])+m_primaryStats[PrimaryStats::Strength]);
	m_derivedStats[DerivedStats::Sequence] = static_cast<int>(m_primaryStats[PrimaryStats::Speed]*2.0f);
	m_derivedStats[DerivedStats::MeleeDamage] =  static_cast<int>(MAX(1.0f, m_primaryStats[PrimaryStats::Strength]-5.0f));
}